/**
 * 
 */
package tests;

import static org.junit.Assert.*;

import java.util.LinkedList;
import java.util.Random;
import java.util.TreeMap;
import java.util.UUID;

import org.junit.BeforeClass;
import org.junit.Test;

import sourceFiles.ETicket;

/**
 * This test class is a unit test for the class ETicket
 * 
 * @author LASO-Team
 * 
 */
public class ETicketTest {
	// static parameters used in the test a defined here
	static private final int RANDOM_TEST_SIZE = 7;
	static private final int[] EDGE_OF_LEGAL_INT_VALUES = { 1, 2 };
	static private final int TEST_SIZE = RANDOM_TEST_SIZE
			+ EDGE_OF_LEGAL_INT_VALUES.length;
	static private final int NUM_TICKETS_PER_RIDE = 10;
	static private int[] rideIDs;

	// end static parameters

	/**
	 * Initiating all the static arrays above with test values, as well as
	 * random parameters (number of tests, TEST_SIZE, is determined by the
	 * number of test values as well as the number of random values
	 * 
	 * @throws Exception
	 */
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		LinkedList<Integer> list = new LinkedList<Integer>();
		int numOfEdgeTests = EDGE_OF_LEGAL_INT_VALUES.length;
		for (int i = 0; i < numOfEdgeTests; i++) { // init the legal value first
			list.add(EDGE_OF_LEGAL_INT_VALUES[i]);
		}
		Random rand = new Random();
		for (int i = 0; i < RANDOM_TEST_SIZE; i++) {
			list.add(rand.nextInt());
		}
		assertTrue(list.size() == TEST_SIZE);
		rideIDs = new int[TEST_SIZE];
		for (int i = 0; i < TEST_SIZE; i++) {
			rideIDs[i] = list.get(i);
		}
	}

	/**
	 * Testing the constructor of the ETicket
	 */
	@Test
	public void testETicketCtor() {
		ETicket ticket = new ETicket();
		assertTrue(ticket != null);
		assertTrue(ticket.getExtremeRidesList().size() == 0);
		assertTrue(ticket.getRegualrRidesTickets() == 0);
	}

	/**
	 * Test that a regular ticket can be added to the ETicket
	 */
	@Test
	public void testAddRegularTicket() {
		ETicket ticket = new ETicket();
		for (int j = 0; j < NUM_TICKETS_PER_RIDE; j++) {
			ticket.addRegularTicket();
			assertTrue(ticket.getRegualrRidesTickets() == (j + 1));
		}
	}

	/**
	 * Test that a regular ticket can be removed from the ETicket
	 */
	@Test
	public void testRemoveRegularTicket() {
		ETicket ticket = new ETicket();
		for (int j = 0; j < NUM_TICKETS_PER_RIDE; j++) {
			ticket.addRegularTicket();
			ticket.removeRegularTicket();
			assertTrue(ticket.getRegualrRidesTickets() == 0);
		}
		for (int j = 0; j < NUM_TICKETS_PER_RIDE; j++) {
			ticket.addRegularTicket();
		}
		assertTrue(ticket.getRegualrRidesTickets() == NUM_TICKETS_PER_RIDE);
		for (int j = 0; j < NUM_TICKETS_PER_RIDE; j++) {
			ticket.removeRegularTicket();
		}
		assertTrue(ticket.getRegualrRidesTickets() == 0);
		ticket.removeRegularTicket();
		assertTrue(ticket.getRegualrRidesTickets() == 0);
	}

	/**
	 * Test that an extreme ticket can be added to the ETicket
	 */
	@Test
	public void testAddExtremeTicket() {
		ETicket ticket = new ETicket();
		for (int i = 0; i < TEST_SIZE; i++) {
			assertTrue(!ticket.getExtremeRidesList().containsKey(rideIDs[i]));
			for (int j = 0; j < NUM_TICKETS_PER_RIDE; j++) {
				ticket.addExtremeTicket(rideIDs[i]);
				assertTrue(ticket.getExtremeRidesList().containsKey(rideIDs[i]));
				assertTrue(ticket.getExtremeRidesList().get(rideIDs[i]) == j + 1);
			}
		}
		for (int i = 0; i < TEST_SIZE; i++) {
			assertTrue(ticket.getExtremeRidesList().containsKey(rideIDs[i]));
			assertTrue(ticket.getExtremeRidesList().get(rideIDs[i]) == NUM_TICKETS_PER_RIDE);
		}
	}

	/**
	 * Test that an extreme ticket can be removed from the ETicket
	 */
	@Test
	public void testRemoveExtremeTicket() {
		ETicket ticket = new ETicket();
		int[] arr = rideIDs;
		for (int i = 0; i < TEST_SIZE; i++) {
			for (int j = 0; j < NUM_TICKETS_PER_RIDE; j++) {
				assertTrue(!ticket.getExtremeRidesList()
						.containsKey(rideIDs[i]));
				ticket.addExtremeTicket(rideIDs[i]);
				assertTrue(ticket.getExtremeRidesList().containsKey(rideIDs[i]));
				assertTrue(ticket.getExtremeRidesList().get(rideIDs[i]) == 1);
				ticket.removeExtremeTicket(rideIDs[i]);
				assertTrue(!(ticket.getExtremeRidesList()
						.containsKey(rideIDs[i])));
				ticket.removeExtremeTicket(rideIDs[i]);
				assertTrue(!ticket.getExtremeRidesList()
						.containsKey(rideIDs[i]));
			}
		}
		for (int i = 0; i < TEST_SIZE; i++) {
			for (int j = 0; j < NUM_TICKETS_PER_RIDE; j++) {
				ticket.addExtremeTicket(rideIDs[i]);
				ticket.getExtremeRidesList().containsKey(rideIDs[i]);
				assertTrue(ticket.getExtremeRidesList().get(rideIDs[i]) == (j + 1));
			}
		}

	}

	/**
	 * Test that the ETicket can return if a ticket exists within it (both for
	 * regular an extreme ticket)
	 */
	@Test
	public void testTicketExists() {
		ETicket ticket = new ETicket();
		assertTrue(!ticket.ticketExists(3, false));
		for (int j = 0; j < NUM_TICKETS_PER_RIDE; j++) {
			ticket.addRegularTicket();
		}
		assertTrue(ticket.ticketExists(3, false));
		for (int i = 0; i < TEST_SIZE; i++) {
			assertTrue(!ticket.ticketExists(rideIDs[i], true));
			for (int j = 0; j < NUM_TICKETS_PER_RIDE; j++) {
				ticket.addExtremeTicket(rideIDs[i]);
				assertTrue(ticket.ticketExists(rideIDs[i], true));
			}
		}
	}

}
